#include <iostream>
#include <memory>
#include <string>

// unique_ptr
class Resource {
public:
    Resource(int id) : id_(id) {
        std::cout << "资源 " << id_ << " 已创建\n";
    }
    ~Resource() {
        std::cout << "资源 " << id_ << " 已销毁\n";
    }
    void doSomething() {
        std::cout << "资源 " << id_ << " 正在执行操作\n";
    }
private:
    int id_;
};

void uniquePtrExample() {
    std::cout << "=== unique_ptr 示例 ===\n";
    
    // 创建 unique_ptr
    std::unique_ptr<Resource> ptr1(new Resource(1));
    
    // 使用 C++11 兼容的方式创建 unique_ptr
    std::unique_ptr<Resource> ptr2(new Resource(2));
    
    // 访问对象成员
    ptr1->doSomething();
    
    // 转移所有权 - 移动语义
    std::unique_ptr<Resource> ptr3 = std::move(ptr1);
    
    // 此时 ptr1 为空
    if (!ptr1) {
        std::cout << "ptr1 现在为空\n";
    }
    
    // ptr3 现在拥有资源
    ptr3->doSomething();
    
    // 释放所有权（不销毁对象）
    Resource* rawPtr = ptr3.release();
    delete rawPtr;  // 需要手动删除
    
    // reset 会销毁当前管理的对象
    ptr2.reset(new Resource(3));
}

// shared_ptr
class SharedResource {
public:
    SharedResource(int id) : id_(id) {
        std::cout << "共享资源 " << id_ << " 已创建\n";
    }
    ~SharedResource() {
        std::cout << "共享资源 " << id_ << " 已销毁\n";
    }
    void showInfo() {
        std::cout << "共享资源 " << id_ << " 仍然存在\n";
    }
private:
    int id_;
};

void sharedPtrExample() {
    std::cout << "\n=== shared_ptr 示例 ===\n";
    
    // 创建 shared_ptr
    std::shared_ptr<SharedResource> ptr1 = std::make_shared<SharedResource>(1);
    
    std::cout << "引用计数: " << ptr1.use_count() << "\n";  // 1
    
    {
        // 共享所有权
        std::shared_ptr<SharedResource> ptr2 = ptr1;
        std::cout << "引用计数: " << ptr1.use_count() << "\n";  // 2
        
        ptr1->showInfo();
        ptr2->showInfo();
        
        // ptr2 离开作用域，引用计数减1
    }
    
    std::cout << "引用计数: " << ptr1.use_count() << "\n";  // 1
    
    // 创建另一个 shared_ptr
    auto ptr3 = std::make_shared<SharedResource>(2);
    
    // 重置 ptr1 指向新的对象
    ptr1 = ptr3;
    std::cout << "ptr3 的引用计数: " << ptr3.use_count() << "\n";  // 2
}

// weak_ptr - Node 需要继承 enable_shared_from_this
class Node : public std::enable_shared_from_this<Node> {
public:
    std::string name;
    std::shared_ptr<Node> next;  // 强引用
    std::weak_ptr<Node> prev;    // 弱引用，避免循环引用
    
    Node(const std::string& n) : name(n) {
        std::cout << "节点 " << name << " 已创建\n";
    }
    
    ~Node() {
        std::cout << "节点 " << name << " 已销毁\n";
    }
    
    void setNext(std::shared_ptr<Node> nextNode) {
        next = nextNode;
        if (nextNode) {
            nextNode->prev = shared_from_this();  // 使用 weak_ptr
        }
    }
    
    void traverse() {
        auto current = shared_from_this();
        while (current) {
            std::cout << "正在访问: " << current->name << "\n";
            
            // 使用 weak_ptr 访问前一个节点
            if (auto prevPtr = current->prev.lock()) {
                std::cout << "  前一个节点: " << prevPtr->name << "\n";
            } else {
                std::cout << "  前一个节点: (无)\n";
            }
            
            current = current->next;
        }
    }
};

void weakPtrExample() {
    std::cout << "\n=== weak_ptr 示例 ===\n";
    
    // 创建循环引用场景
    auto node1 = std::make_shared<Node>("A");
    auto node2 = std::make_shared<Node>("B");
    auto node3 = std::make_shared<Node>("C");
    
    // 建立双向链接（使用 weak_ptr 避免循环引用）
    node1->setNext(node2);
    node2->setNext(node3);
    
    // 遍历节点
    node1->traverse();
    
    // 检查 weak_ptr 是否有效
    if (auto locked = node1->prev.lock()) {
        std::cout << "前一个节点存在: " << locked->name << "\n";
    } else {
        std::cout << "前一个节点已被销毁\n";
    }
}

// 正确的例子 - 使用 weak_ptr 打破循环引用
class GoodNode {
public:
    std::string name;
    std::weak_ptr<GoodNode> partner;  // 使用 weak_ptr
    
    GoodNode(const std::string& n) : name(n) {
        std::cout << "良好节点 " << name << " 已创建\n";
    }
    
    ~GoodNode() {
        std::cout << "良好节点 " << name << " 已销毁\n";
    }
};

void circularReferenceExample() {
    std::cout << "\n=== 循环引用示例 ===\n";
    
    std::cout << "良好示例（无内存泄漏）:\n";
    // 正确示例：使用 weak_ptr
    {
        auto nodeA = std::make_shared<GoodNode>("A");
        auto nodeB = std::make_shared<GoodNode>("B");
        
        nodeA->partner = nodeB;  // weak_ptr 不增加引用计数
        nodeB->partner = nodeA;
        
        std::cout << "引用计数 - A: " << nodeA.use_count() 
                  << ", B: " << nodeB.use_count() << "\n";
        
        // 访问 weak_ptr
        if (auto partner = nodeA->partner.lock()) {
            std::cout << "节点 A 的伙伴: " << partner->name << "\n";
        }
    }  // nodeA 和 nodeB 会被正确销毁
}

int main() {
    uniquePtrExample();
    sharedPtrExample();
    weakPtrExample();
    circularReferenceExample();
    
    return 0;
}
